home *** CD-ROM | disk | FTP | other *** search
-
- .386p
- code32 segment para public use32
- assume cs:code32,ds:code32
-
- include 386power.inc
- align byte
-
- ; This module uses the space between
- ; _LoMemBase and lomemtop for buffering file transferts to extended memory
-
-
- fname_buf db 256 dup(0) ; buffer fo filename
-
- ; _FOpen: Opens a file and returns its handle into V86bx
- ; In:
- ; ESI -> ASCIIZ filename max. 255 bytes long
- ; AL == file mode: 00 = Read Only
- ; 01 = Write Only (create it if it doesn't exist)
- ; Out:
- ; if carry set then
- ; Error opening file
- ; else
- ; File opened succesfully
- ; V86bx = file handle
-
- public _FOpen
- _FOpen:
- pushad
-
- mov ebp,eax
-
- mov cl,1
- mov edi,offset fname_buf
- zerother:
- lodsb
- inc cl ; when 255 is reached, this will be resetted
- je topped
- stosb
- or al,al
- jne zerother
- topped: mov esi,offset fname_buf
- mov byte ptr [edi],0 ;put a NUL for safety
- add esi,_Code32Base ; get a linear address
- mov ecx,esi
- mov V86cx,0 ; clear all file attributes OR access mask
- shr esi,4 ; segment into dx
- and ecx,0fh ; offset into cx
- mov eax,ebp ; get eax back
- mov V86ax,3D00h
- cmp al,00
- je gopenr ; al=00 --> open to read
- mov V86ax,3C01h ; else --> open to write
- gopenr:
- mov V86dx,cx ; send seg:ofs
- mov V86ds,si ;
- mov al,21h ; select interrupt
- call _ExecINT ; go V86
- mov ax,V86ax ;
- mov V86bx,ax ; copy handle to V86bx
- popad
- ret
-
- ; _FClose Closes file with handle V86bx
- ; In:
- ; V86bx = file handle
- public _FClose
- _FClose:
- push eax
- mov V86ax,3e00h
- mov al,21h
- call _ExecINT
- pop eax
- ret
-
-
- public _FSeek
-
- ; _FSeek Seek position in file
- ; In:
- ; V86bx = file handle
- ; EAX = signed offset to move to
- ; DL = from: 0-beginning of file, 1-current location, 2-end of file
- ; Out:
- ; If carry clear then Seek done
- ; EAX = new offset from beginning of file
- ; else EAX trashed
-
- _FSeek:
- push edx
- mov V86ah,42h
- mov V86al,dl
- mov V86dx,ax
- shr eax,16
- mov V86cx,ax
- mov al,21h
- call _ExecINT
- jc fserr
- mov ax,V86dx
- shl eax,16
- mov ax,V86ax
- fserr:
- pop edx
- ret
-
- public _FSize
-
- ; _FSize Get size of file
- ; In:
- ; V86bx = file handle
- ; Out:
- ; if Carry Clear then File exist
- ; EAX = size of file
- ; else error, EAX trashed
-
- _FSize: push edx
- mov dl,01h ; get current file position
- xor eax,eax ;
- call _FSeek ;
- push eax ; save current file position
-
- mov dl,02 ; seek to end of file
- xor eax,eax ;
- call _FSeek ;
-
- pop edx ; restore current file position
-
- push eax ; save file lenght
-
- mov eax,edx ; restore file pointer
- mov dl,00 ;
- call _FSeek ;
-
- pop eax ; restore result
- ; EAX = FILE SIZE
- pop edx
- ret
-
- ; _FRead Reads a block from a file with handle V86bx
- ; In: V86bx = file handle
- ; EDI = base address of block ( relative offset)
- ; into extended memory
- ; EAX = size of block
- ; Out: If carry clear
- ; N.B. The space between _LoMemBase and _LoMemTop is used as a
- ; "transition buffer" if EDI points into extended memory
-
- public _FRead
- _FRead:
- pushad
- mov ebp,_LoMemBase
- mov edx,eax ; copy into EDX size of block to read
- mov ebx,_LoMemTop ;
-
- cmp edi,ebp ;
- jb @nouppa ; low memory destination, write directly to it
- ; high memory destination, use low memory as a buffer
- mov ecx,0FFE0h ; make sure we don't have false wraps
- sub ebx,_LoMemBase ;
- and bl,cl ; get free low memory (paragraph aligned)
- cmp ebx,ecx
- jb @rsmall
- mov ebx,ecx ; read 0FFF0 bytes a time
- @rsmall: ; ebx = size of buffer in low memory
- add ebp,_Code32Base ; convert to linear address
- @rchunk:
- cmp ebx,edx
- jb @rfittrans ; if (bytes_to_read > buffer) then read another chunk
- mov ebx,edx ; else this is the last chunk, make it fit
- @rfittrans: ; ebx = size of chunk to read
-
- mov esi,ebp ; convert linear address to seg:ofs
- mov ecx,ebp ;
- shr esi,4 ;
- and ecx,0Fh ;
- mov V86ds,si ;
- mov V86dx,cx ;
-
- mov V86cx,bx ; chunk size
-
- mov V86ah,3fh ; read chunk
- mov al,21h ;
- call _ExecINT ;
- jc @rfloaderr ; get out if error
-
- mov esi,_LoMemBase ;
- mov ecx,ebx ; move up this chunk
- rep movsb ;
- sub edx,ebx ; update counter of bytes to read
- jne @rchunk ; end of block ? if not at the end, read next chunk
- clc ; say, no error
- @rfloaderr:
- popad
- ret
- @rflucked:
- stc ; say, error
- popad
- ret
-
- @nouppa: ; load into low memory
- mov edx,eax
- mov ebx,0FFF0h
- ; get linear address
- mov ebp,edi
- add ebp,_Code32Base
- @lrchunk:
- cmp ebx,edx
- jbe @lrfittrans ; if (bytes_to_read > buffer) then read another chunk
- mov ebx,edx ; else this is the last chunk, make it fit
- @lrfittrans: ; ebx = size of chunk to read
-
- mov esi,ebp ; convert linear address to seg:ofs
- mov ecx,ebp ;
- shr esi,4 ;
- mov V86ds,si ;
- and ecx,0Fh ;
- mov V86dx,cx ;
-
- mov V86cx,bx ; chunk size
-
- mov V86ah,3fh ; read chunk
- mov al,21h ;
- call _ExecINT ;
- jc @lrfloaderr ; get out if error
- add ebp,ebx ; move forward the linear pointer
- sub edx,ebx ; update counter of bytes to read
- jne @lrchunk ; end of block ? if not at the end, read next chunk
- clc ; say, no error
- @lrfloaderr:
- popad
- ret
-
- ; standard 386file error messages
-
- eropen db 'ERROR WHILE OPENING FILE TO READ FROM',CR,LF,CR,LF,'$'
- ewopen db 'ERROR WHILE OPENING FILE TO WRITE TO',CR,LF,CR,LF,'$'
- eracc db 'ERROR WHILE READING FROM FILE',CR,LF,CR,LF,'$'
- ewacc db 'ERROR WHILE WRITING TO FILE',CR,LF,CR,LF,'$'
-
- ; _FLoad Loads a file with ASCIIZ name pointed by DS:ESI (max 255 bytes)
- ; Out: If carry clear
- ; EAX = file size
- ; The file gets loaded starting from _HiMemBase
- ; The space between _LoMemBase and _LoMemTop is used as a
- ; "transition buffer"
- ; N.B. _LoMemBase and _HiMemBase are left as they were
- ; BEFORE calling _FLoad, what will you do with the heaps
- ; is up to you ( you can update them using the file size
- ; or simply do nothing and "discard" the loaded data ).
- ; Why use extended mem instead of dos mem ? Because dos mem
- ; is precious, it's the only place where you can put things directly
- ; accessible in 'real' and protected mode.
-
- public _FLoad
- _FLoad: ; ds:esi = ptr to ASCIIZ file name
- push edi
- push ebp
- mov al,0 ; read from file
- mov _386Return,offset eropen
- call _FOpen
- jc @flucked ; Oops! Cannot open file
- call _FSize
- jc @flucked ; Oops! Seek problems
- mov _386Return,offset eracc
- mov edi,_HiMemBase ; Is there enough free space in high memory ?
- mov ebp,_HiMemTop ;
- sub ebp,edi ;
- cmp eax,ebp ;
- jnbe @flucked ; Oops! File too big
- call _FRead
- jc @floaderr
- mov _386Return, offset _386Terminator
- call _FClose ; hasta la vista, baby
- clc
- @floaderr:
- pop ebp
- pop edi
- ret
- @flucked:
- pop ebp
- pop edi
- stc
- ret
-
- ; _LoFLoad
- ; Loads a file with ASCIIZ name pointed by DS:ESI (max 255 bytes)
- ; Out: If carry clear
- ; EAX = file size
- ; The file gets loaded starting from _LoMemBase
- ; Use this to directly load things into dos memory
-
- public _LoFLoad
- _LoFLoad: ; ds:esi = ptr to ASCIIZ file name
- push edi
- push ebp
- mov _386Return,offset eropen
- mov al,0 ; read from file
- call _FOpen
- jc @flucked ; Oops! Cannot open file
- call _FSize
- jc @flucked ; Oops! Seek problems
- mov _386Return,offset eracc
- mov edi,_LoMemBase
- mov ebp,_LoMemTop
- sub ebp,edi
- cmp eax,ebp
- ja @flucked ; Oops! File too big
- call _FRead
- jc @lfloaderr
- mov _386Return,offset _386Terminator
- call _FClose ; hasta la vista, baby
- clc
- @lfloaderr:
- pop ebp
- pop edi
- ret
-
- ; _FWrite Writes a block of memory to file with handle V86bx
- ; In: V86bx = file handle
- ; esi = buffer base (relative address)
- ; eax = file size
- ; Out: If carry clear
- ; file write done
-
- public _FWrite
- _FWrite:
- pushad
- mov edx,eax ; edx = counter of bytes to move
- mov ebp,(640*1024) ;
- sub ebp,_Code32Base ; code32-relative offset of top 640k
- cmp esi,ebp ; is source block under the 640k dos limit ?
- jb @writedirect
-
- mov ebp,_LoMemBase
-
- mov ecx,0FFF0h ;max. transfert buffer (paragraph aligned)
-
- mov ebx,_LoMemTop ;
- sub ebx,ebp ; available low memory
-
- and bl,cl ; paragraph align
-
- cmp ebx,ecx ; put into ebx the smallest
- jb @wfull ;
- mov ebx,ecx ;
-
- @wfull: ; ebx = size of transfert buffer
- add ebp,_Code32Base ; LINEAR address of _LoMemBase
- @wchunk:
- cmp ebx,edx ;
- jbe @wafittrans ;
- mov ebx,edx ; if this is the last chunk, make it fit
- @wafittrans: ; ebx = bytes to move this time
-
- mov edi,_LoMemBase ;
- mov ecx,ebx ;
- rep movsb ; move DOWN TO LOW DOS MEMORY a chunk
-
- mov edi,ebp ; linear to seg:ofs
- mov ecx,ebp ;
- shr edi,4 ;
- mov V86ds,di ;
- and ecx,0Fh ;
- mov V86dx,cx ;
-
- mov V86cx,bx ;
- mov V86ah,40h ;
- mov al,21h ; translate & write block
- call _ExecINT ;
- jc @wfsaverr
-
- sub edx,ebx ;
- jne @wchunk ; loop if there are other blocks
- popad
- clc
- ret
- @wfsaverr:
- popad
- stc
- ret
-
- @writedirect:
- mov edx,eax
- ; edx = size of block
- mov ebx,0FFF0h
- ; ebx = size of transfert buffer
- mov ebp,esi ; LINEAR address of esi
- add ebp,_Code32Base
- @lwchunk:
- cmp ebx,edx ;
- jbe @lwafittrans ;
- mov ebx,edx ; if this is the last chunk, make it fit
- @lwafittrans: ; ebx = bytes to move this time
-
- mov edi,ebp ; linear to seg:ofs
- mov ecx,ebp ;
- shr edi,4 ;
- mov V86ds,di ;
- and ecx,0Fh ;
- mov V86dx,cx ;
-
- mov V86cx,bx ;
- mov V86ah,40h ;
- mov al,21h ; translate & write block
- call _ExecINT ;
- jc @wfsaverr
- add ebp,ebx ;
- sub edx,ebx ;
- jne @lwchunk ; loop if there are other blocks
- popad
- clc
- ret
-
- ; _FSave Saves a block of memory
- ; into the file with ASCIIZ name
- ; In:
- ; esi = ptr to asciiz file name in low memory
- ; edi = buffer base
- ; eax = file size
- ; Out: If carry clear
- ; file write done
-
- public _FSave
- _FSave:
- push esi
- push eax
- mov _386Return,offset ewopen
- mov al,1
- call _FOpen
- jc @fsaverr
- mov _386Return,offset ewacc
- mov eax,[esp]; restore block size into eax
- mov esi,edi
- call _FWrite
- jc @fsaverr
- call _FClose
- mov _386Return,offset _386Terminator
- clc
- @fsaverr:
- pop eax
- pop esi
- ret
-
- code32 ends
- end
-
-